package physicsModeler;

import java.awt.*;
import java.awt.image.*;

import javax.swing.*;

public class Screen 
{
	
	GraphicsDevice graphicsDev;
	public Screen()
	{
		GraphicsEnvironment graphicsEnv = GraphicsEnvironment.getLocalGraphicsEnvironment(); // returns machines local environment
		graphicsDev = graphicsEnv.getDefaultScreenDevice();                                  // gives users screen to video card
	}
	
////////////////////////Getters/Setters/////////////////////////////////////////////////////////////////////////////////////////////
	public GraphicsDevice getGraphicsDev()                 { return graphicsDev;                   }
	public void setGraphicsDev(GraphicsDevice graphicsDev) { this.graphicsDev = graphicsDev;       } 
	// get all compatible display modes
	public DisplayMode[] getCompatibleDisplayModes()       { return graphicsDev.getDisplayModes(); }
	public Window getFullScreenWindow()                    { return graphicsDev.getFullScreenWindow(); }
	public int getWidth()
	{
		Window window = graphicsDev.getFullScreenWindow();
		if (window != null)
		{
			return window.getWidth();
		}
		else
			return 0;
	}
	public int getHeight()
	{
		Window window = graphicsDev.getFullScreenWindow();
		if (window != null)
		{
			return window.getHeight();
		}
		else
			return 0;
	}
////////////////////////Getters/Setters/////////////////////////////////////////////////////////////////////////////////////////////	
	
	public DisplayMode FindCompatibleMode(DisplayMode modes[])
	{
		DisplayMode workingModes[] = graphicsDev.getDisplayModes();
		for(int x = 0; x < modes.length; x++)
		{
			for (int y = 0; y < workingModes.length; y++)
			{
				if(DisplayModesMatch(modes[x], workingModes[y]))
				{
					return modes[x];
				}
			}
		}
		return null; // needs to be changed
	}
	
	// make frame full screen
	public void setFullScreen(DisplayMode displayMode)
	{
		JFrame frame = new JFrame();
		frame.setUndecorated(true);
		frame.setIgnoreRepaint(true); // We will be handling repaint explicitly in our games main loop.
		frame.setResizable(false);
		frame.setBackground(Color.black);
		graphicsDev.setFullScreenWindow(frame);
		
		if(displayMode != null && graphicsDev.isDisplayChangeSupported())
		{
			try
			{
				graphicsDev.setDisplayMode(displayMode);
			} catch(Exception exception) {}
		}
		else {/*... needed*/}
		
		frame.createBufferStrategy(2); // built in buffering (not sure if performance will be better or worse with this method compared to a custom built one)
	}
	
	// set graphics = to this returned graphics2d
	public Graphics2D getGraphics()
	{
		Window window = graphicsDev.getFullScreenWindow();
		if (window != null)
		{
			BufferStrategy strategy = window.getBufferStrategy();
			return (Graphics2D) strategy.getDrawGraphics(); // using our buffer strategy on a graphics2d object and casting graphics to graphics2D(for better anti-aliasing)
		}
		
		else
			return null;
	}
	
	// updates display
	public void update()
	{
		Window window = graphicsDev.getFullScreenWindow();
		if (window != null)
		{
			BufferStrategy strategy = window.getBufferStrategy();
			if (!strategy.contentsLost())  // If our volatile image is not lost
			{
				strategy.show();           // makes buffered image available
			}
		}
	}	
	
	// Some necessary logic to find a working display mode on any machine
	private boolean DisplayModesMatch(DisplayMode modes, DisplayMode workingModes) 
	{
		if (modes.getWidth()    != workingModes.getWidth()  ||
			modes.getHeight()   != workingModes.getHeight())
		{
		    return false;
		}
		
		if (modes.getBitDepth()        != DisplayMode.BIT_DEPTH_MULTI &&
			workingModes.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI &&
			modes.getBitDepth()        != workingModes.getBitDepth())
		{
			return false;
		}
		
		if (modes.getRefreshRate()        != DisplayMode.REFRESH_RATE_UNKNOWN &&
			workingModes.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN &&
			modes.getRefreshRate()        == workingModes.getRefreshRate())
		{
			return false;
		}
		
		return true;
			
	}
	
	// get out of fullscreen
	public void RestoreScreen()
	{
		Window window = graphicsDev.getFullScreenWindow();
		if (window != null)
		{
			window.dispose();
		}
		graphicsDev.setFullScreenWindow(null);
	}	


}
